/**
 * @brief 使用kobject_create_and_add和sysfs_create_group创建sysfs文件
*/

#include <linux/init.h>             
#include <linux/module.h>
#include <linux/device.h>


MODULE_LICENSE("GPL");
MODULE_AUTHOR("mdy");
MODULE_DESCRIPTION("sysfs demo");
MODULE_VERSION("0.1");

static unsigned long input_v = 0;
static unsigned long output_sqrt = 0;

/*************************kobject***************************/
static struct kobject *kob;
 
static ssize_t output_sqrt_show(struct device *dev, struct device_attribute*attr, char *buf)
{
    return sprintf(buf,"sqrt = %ld\n", output_sqrt);
}
 
static ssize_t input_v_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t len)
{
    int ret = sscanf(buf, "%ld", &input_v);
    if (ret == 1)
    {
        output_sqrt = int_sqrt(input_v);
    }
    
    return len;       //必须返回count，否则会死循环
}

static DEVICE_ATTR(output_attr, S_IRUSR | S_IRGRP | S_IROTH, output_sqrt_show, NULL);
static DEVICE_ATTR(input_attr, S_IWUSR | S_IWGRP, NULL, input_v_store);     //不允许S_IWOTH


static struct attribute *demo_attrs[] = {
    &dev_attr_output_attr.attr,
    &dev_attr_input_attr.attr,
    NULL,
};
 
static struct attribute_group attr_g = {
    .name = "kobject_test",
    .attrs = demo_attrs,
};

 
static int __init demo_init(void){
    kob = kobject_create_and_add("obj_test",kernel_kobj->parent);
    sysfs_create_group(kob, &attr_g);
    return 0;
}
 
 
static void __exit demo_exit(void){
    sysfs_remove_group(kob, &attr_g);
    kobject_put(kob);
}
 
 
module_init(demo_init);
module_exit(demo_exit);